/*
 * @(#)AtnaUtils.java
 * Date 2013-11-02
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.atna.client.utils;

import javax.xml.datatype.XMLGregorianCalendar;

import us.hornerscorners.lamppost.atna.client.AtnaContext;

import us.hornerscorners.lamppost.model.audit.AuditContext;
import us.hornerscorners.lamppost.model.audit.AuditMessage;

import us.hornerscorners.lamppost.model.audit.AuditMessage.ActiveParticipant;

import us.hornerscorners.lamppost.model.audit.AuditSourceIdentificationType;
import us.hornerscorners.lamppost.model.audit.CodedValueType;
import us.hornerscorners.lamppost.model.audit.ParticipantObjectIdentificationType;
import us.hornerscorners.lamppost.model.audit.TypeValuePairType;

import us.hornerscorners.lamppost.utils.UTCDateUtils;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-11-02
 * @author         Jim Horner
 */
public class AtnaUtils {

    /** Field description */
    private static final String QUERY_ENCODING = "QueryEncoding";

    /** Field description */
    private static final Short SHORT_TWO = Short.valueOf("2");

    /** Field description */
    private static final byte[] UTF8_BYTES = "UTF-8".getBytes();

    /**
     * Method description
     *
     *
     *
     * @param auditContext
     * @return
     */
    public static AuditSourceIdentificationType createAuditSource(
            AuditContext auditContext) {

        AuditSourceIdentificationType result = new AuditSourceIdentificationType();

        result.setAuditSourceID(auditContext.getTransactionContext().getTransId());
        result.setAuditEnterpriseSiteID(auditContext.getServiceConfig().getId());

        String codeSystem =
            String.format("LAMPPOST %s Codes",
                          auditContext.getServiceConfig().getServiceType().getTypeName());

        result.getAuditSourceTypeCode().add(AtnaUtils.createCodedValue("TRANSID",
                codeSystem, "Transaction Identification"));

        return result;
    }

    /**
     * Method description
     *
     *
     * @param auditContext
     *
     * @return
     */
    public static ActiveParticipant createClientDestinationParticipant(
            AuditContext auditContext) {

        ActiveParticipant result = new AuditMessage.ActiveParticipant();

        result.setUserID(auditContext.getAddressContext().getTo());
        result.setAlternativeUserID(auditContext.getAddressContext().getMessageId());
        result.setUserIsRequestor(Boolean.FALSE);
        result.getRoleIDCode().add(AtnaUtils.createCodedValue("110152", "DCM",
                "Destination"));
        result.setNetworkAccessPointID(auditContext.getAddressContext().getRemoteIp());
        result.setNetworkAccessPointTypeCode(SHORT_TWO);

        return result;
    }

    /**
     * Method description
     *
     *
     * @param atnaContext
     * @param auditContext
     *
     * @return
     */
    public static ActiveParticipant createClientSourceParticipant(
            AtnaContext atnaContext, AuditContext auditContext) {

        ActiveParticipant result = new ActiveParticipant();

        result.setUserID(auditContext.getAddressContext().getReplyTo());
        result.setAlternativeUserID(atnaContext.getProcessId());
        result.setUserIsRequestor(Boolean.TRUE);
        result.getRoleIDCode().add(AtnaUtils.createCodedValue("110153", "DCM", "Source"));
        result.setNetworkAccessPointID(atnaContext.getIpAddress());
        result.setNetworkAccessPointTypeCode(SHORT_TWO);

        return result;
    }

    /**
     * Method description
     *
     *
     * @param code
     * @param codeSystem
     * @param displayName
     *
     * @return
     */
    public static CodedValueType createCodedValue(String code, String codeSystem,
            String displayName) {

        CodedValueType result = new CodedValueType();

        result.setCode(code);
        result.setCodeSystem(codeSystem);
        result.setDisplayName(displayName);

        return result;
    }

    /**
     * Method description
     *
     *
     * @param atnaContext
     * @param auditContext
     *
     * @return
     */
    public static ActiveParticipant createDestinationParticipant(AtnaContext atnaContext,
            AuditContext auditContext) {

        ActiveParticipant result = new ActiveParticipant();

        result.setUserID(auditContext.getAddressContext().getTo());
        result.setAlternativeUserID(atnaContext.getProcessId());
        result.setUserIsRequestor(Boolean.FALSE);
        result.getRoleIDCode().add(AtnaUtils.createCodedValue("110152", "DCM",
                "Destination"));
        result.setNetworkAccessPointID(atnaContext.getIpAddress());
        result.setNetworkAccessPointTypeCode(SHORT_TWO);

        return result;
    }

    /**
     * Method description
     *
     *
     *
     * @param pidcx
     * @return
     */
    public static ParticipantObjectIdentificationType createPatientIdentification(
            String pidcx) {

        ParticipantObjectIdentificationType result =
            new ParticipantObjectIdentificationType();

        result.setParticipantObjectTypeCode(Short.valueOf("1"));
        result.setParticipantObjectTypeCodeRole(Short.valueOf("1"));
        result.setParticipantObjectIDTypeCode(AtnaUtils.createCodedValue("2", "RFC-3881",
                "Patient Number"));

        result.setParticipantObjectID(pidcx);

        return result;
    }

    /**
     * Method description
     *
     *
     * @param auditContext
     *
     * @return
     */
    public static ActiveParticipant createSourceParticipant(AuditContext auditContext) {

        ActiveParticipant result = new AuditMessage.ActiveParticipant();

        result.setUserID(auditContext.getAddressContext().getReplyTo());
        result.setAlternativeUserID(auditContext.getAddressContext().getMessageId());
        result.setUserIsRequestor(Boolean.TRUE);
        result.getRoleIDCode().add(AtnaUtils.createCodedValue("110153", "DCM", "Source"));
        result.setNetworkAccessPointID(auditContext.getAddressContext().getRemoteIp());
        result.setNetworkAccessPointTypeCode(SHORT_TWO);

        return result;
    }

    /**
     * Method description
     *
     * }
     *
     * public static AuditSourceIdentificationType createAuditSource(IServiceConfig serviceConfig) {
     *   throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     *
     * @return
     */
    public static XMLGregorianCalendar createTimeStamp() {

        return UTCDateUtils.nowXMLGregorianCalendar();
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static TypeValuePairType createUTF8Detail() {

        TypeValuePairType result = new TypeValuePairType();

        result.setType(QUERY_ENCODING);
        result.setValue(UTF8_BYTES);

        return result;
    }
}
